昨天將 domain 設定好,確定目前的 mydocker.online 是已經跟我們的服務連上的, docker-compose.yml 目前長成如下,那我們今天要一步步來除錯。
version: "3.9"
services:
  app:
    image: krystallll/docker_test:1.0
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
    restart: on-failure
    ports:
      - 80:3000
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.app.loadbalancer.server.port=3000"
      - "traefik.http.routers.app.rule=Host(`mydocker.online`)"`
      - "traefik.http.routers.app.entrypoints=web"
      - "traefik.http.routers.app.tls=true"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
  db:
    image: postgres:14-alpine
    restart: on-failure
    environment:
      POSTGRES_PASSWORD: password
  # traefik:
    # image: traefik:v2.10
    # command:
      # - "--api.insecure=true"
      # - "--providers.docker=true"
      # - "--providers.docker.exposedbydefault=false"
      # - "--entrypoints.web.address=:80"
      # - "--entrypoints.websecure.address=:443"
      # - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      # - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      # - "--certificatesresolvers.letsencrypt.acme.email=krystal@5xcampus.com"
      # - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    # ports:
      # - "80:80"
      # - "443:443"
      # - "8080:8080"
    # volumes:
      # - "./letsencrypt:/letsencrypt"
      # - /var/run/docker.sock:/var/run/docker.sock
當我將上述註解都打開,並且移除 app 服務的 ports: - 80:3000 (移除是因為 traefik 服務有 80 port ,所以可以由他指揮去 app 服務) 後,重新 docker-compose up ,再去網址 https://mydocker.online 時,不外乎一樣是 404 page not found。
統整一下我搜集到的可能連接不上的所有原因,來一一檢查修改
因為我的 docker-compose.yml 沒有特別設定在哪個網路下執行,所以我們就先來設定一下,確保我的 docker-compose 的所有服務都在同個網路下執行,可以互相通信,如果大家對於 Network 不太熟悉,可以參考 DAY 6 Docker Network(網路)容器與容器間的橋樑
首先我要先建立一個網路,我就取名為 development 好了,那就在我的 AWS EC2 instance 終端機裡面,我可以先確認現在的 Network 有哪些
docker network ls
再來建立名為 development 的網路
docker network create development

看到這串 SHA 值就代表建立成功!
接著去 docker-compose.yml 加上這個 development 的網路
version: "3.9"
services:
  app:
    image: krystallll/docker_test:1.0
    networks:
      - development
    (...中間略)
  db:
    image: postgres:14-alpine
    networks:
      - development
    (...中間略)
  traefik:
    image: traefik:v2.10
    networks:
      - development
    (...中間略)
networks:
  development:
    external: true
這邊只有我加上網路的片段,其他都跟本來一樣就先省略。
接者每當我們前面要去 port 3000 或是 8080 我們都有檢查 Security Groups ,但是現在我們在 docker-compose.yml 的 traefik 服務,是開了三個 port 80、443、8080
ports:
   - "80:80"
   - "443:443"
   - "8080:8080"
所以現在要去檢查 Security Groups 是否都有開?

發現少了 https 的 443 port,所以我加開了 443 port 的 Security Groups
我重新翻閱了官網,找到以下兩個 靜態設置 以及 docker labels 這邊列出了所有的設置,我重新配置了一下我的 docker-compose.yml
version: "3.9"
services:
  app:
    image: krystallll/docker_test:1.0
    networks:
      - development
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
    restart: on-failure
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app-http.entrypoints=web"
      - "traefik.http.routers.app-https.entrypoints=websecure"
      - "traefik.http.routers.app-http.rule=Host(`mydocker.online`)"
      - "traefik.http.routers.app-https.rule=Host(`mydocker.online`)"
      - "traefik.http.routers.app-https.tls=true"
      - "traefik.http.routers.app-https.tls.certresolver=letsencrypt"
      - "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
      - "traefik.http.routers.app-http.middlewares=https-only"
      - "traefik.http.routers.app-https.service=app"
      - "traefik.http.services.app.loadbalancer.server.port=3000"
  db:
    image: postgres:14-alpine
    networks:
      - development
    restart: on-failure
    environment:
      POSTGRES_PASSWORD: password
  traefik:
    image: traefik:v2.10
    networks:
      - development
    restart: on-failure
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt=true"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencrypt.acme.email=krystal@5xcampus.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - /var/run/docker.sock:/var/run/docker.sock
networks:
  development:
    external: true
以下來一一說明:
--api.insecure=true
traefik.enable=true 就好--providers.docker.exposedbydefault=false
web 的入口點,他的 port 是 80--entrypoints.web.address=:80
websecure 的入口點,他的 port 是 443--entrypoints.websecure.address=:443
--certificatesresolvers.letsencrypt=true
--certificatesresolvers.letsencrypt.acme.httpchallenge=true
--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
--certificatesresolvers.letsencrypt.acme.email=krystal@5xcampus.com
--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
traefik.enable=true
app-http 是我取的名字,代表 app-http 這個東東是走 web 這條路,因為 web 正常是 http ,所以我就直接取名為 app-http
traefik.http.routers.app-http.entrypoints=web
app-https 是走 websecure 這條路traefik.http.routers.app-https.entrypoints=websecure
app-http 跟 app-https 的 Host 是 mydocker.online
traefik.http.routers.app-http.rule=Host(`mydocker.online`)
traefik.http.routers.app-https.rule=Host(`mydocker.online`)
app-https 是走 443 也就是 https 所以設定 true 代表他需要使用我們申請的憑證traefik.http.routers.app-https.tls=true
traefik.http.routers.app-https.tls.certresolver=letsencrypt
traefik.http.middlewares.https-only.redirectscheme.scheme=https
traefik.http.routers.app-http.middlewares=https-only
traefik.http.routers.app-https.service=app
traefik.http.services.app.loadbalancer.server.port=3000
docker-compose up
去瀏覽器輸入網址 mydocker.online

搞了這麼多天就為了這個 https 的鎖呀🥹🎉🎉🎉
然後再根據按鈕按一按可以得來朝思暮想的首頁。

另外也可以自己試試,硬是將網址輸入 http://mydocker.online ,他也會自動轉址到 https://mydocker.online 😍😍😍